package com.hyperfix.washer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyperfix.common.exception.CustomException;
import com.hyperfix.common.holder.UserHolder;
import com.hyperfix.feign.clients.JobClient;
import com.hyperfix.models.common.R;
import com.hyperfix.models.user.dtos.UserDTO;
import com.hyperfix.models.washer.dtos.PipelineDTO;
import com.hyperfix.models.washer.dtos.PipelineS;
import com.hyperfix.models.washer.dtos.PipelineT;
import com.hyperfix.models.washer.pojos.Monitor;
import com.hyperfix.models.washer.pojos.Pipeline;
import com.hyperfix.models.washer.pojos.Station;
import com.hyperfix.models.washer.vos.PipelineQueryVO;
import com.hyperfix.models.washer.vos.PipelineVO;
import com.hyperfix.washer.common.MonitorRegistrar;
import com.hyperfix.washer.mapper.MonitorMapper;
import com.hyperfix.washer.mapper.PipelineMapper;
import com.hyperfix.washer.mapper.StationMapper;
import com.hyperfix.washer.service.PipelineService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author JiangChunYu
 * 2024/4/14
 */
@Transactional
@Service
public class PipelineServiceImpl extends ServiceImpl<PipelineMapper, Pipeline> implements PipelineService {
    @Resource
    private PipelineMapper pipelineMapper;
    @Resource
    private MonitorMapper monitorMapper;
    @Resource
    private StationMapper stationMapper;
    @Resource
    private MonitorRegistrar monitorRegistrar;
    @Resource
    private JobClient jobClient;

    @Override
    public R<IPage<PipelineDTO>> list(Integer pageNum, Integer size, PipelineQueryVO pipelineQueryVO) {
        IPage<PipelineDTO> pipelineDTOIPage = new Page<>(pageNum, size);
        pipelineDTOIPage = pipelineMapper.listPipelineDTO(pipelineDTOIPage, pipelineQueryVO);
        return R.success(pipelineDTOIPage);
    }

    @Override
    public R<Pipeline> queryInit() {
        UserDTO userDTO = UserHolder.getUser();
        Integer userId = userDTO.getId();
        Pipeline pipeline = pipelineMapper.selectOneByUserId(userId);
        // 没有初始监控管线，新增一条数据
        if (pipeline == null) {
            boolean success = monitorMapper.saveByFirstPipeline(userId);
            if (!success) {
                throw new CustomException("系统错误，添加初始监控管线失败");
            }
            pipeline = pipelineMapper.selectOneByUserId(userId);
        }
        return R.success(pipeline);
    }

    @Override
    public R<String> togglePipeline(String pipelineName) {
        UserDTO userDTO = UserHolder.getUser();
        Integer userId = userDTO.getId();
        Monitor monitor = monitorRegistrar.getMonitor(userId);
        if (monitor == null) {
            return R.error("未连接ws，请稍后重试");
        }
        Integer pipelineId = pipelineMapper.selectIdByName(pipelineName);
        monitor.setPipelineId(pipelineId);
        monitorMapper.updateById(monitor);
        return R.success("切换监控管线成功");
    }

    @Override
    public R<List<PipelineS>> listAllWithStation() {
        List<Station> stations = stationMapper.selectList(new LambdaQueryWrapper<>());
        List<PipelineS> pipelineSList = new ArrayList<>(stations.size());
        stations.forEach(station -> {
            List<Pipeline> pipelines = pipelineMapper.selectList(new LambdaQueryWrapper<Pipeline>().eq(Pipeline::getStationId, station.getId()));
            pipelineSList.add(new PipelineS(station, pipelines));
        });
        if (pipelineSList.isEmpty() || pipelineSList.get(0).getPipelines().isEmpty()) {
            return R.success(Collections.emptyList());
        }
        return R.success(pipelineSList)
                .add("defaultPipelineId", pipelineSList.get(0).getPipelines().get(0).getId());
    }

    @Override
    public R<String> enablePipeline(Integer pipelineId, Integer stop) {
       return jobClient.changeStatus(pipelineId, stop);
    }

    @Override
    public R<String> changeCycle(Integer pipelineId, Long period) {
        return jobClient.changeCycle(pipelineId, period);
    }

    @Override
    public List<PipelineT> listAllWithStatus() {
        return pipelineMapper.selectAllWithStatus();
    }

    @Override
    public R<String> updatePipeline(PipelineVO pipelineVO) {
        boolean isUpdated = pipelineMapper.updatePipeline(pipelineVO);
        if (!isUpdated) {
            throw  new CustomException("管线信息修改失败，管线不存在");
        }
        return R.success("管线信息修改成功");
    }
}
